//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <core.h>
#include <_hal.h>

#if defined(_UDBAGENT)
void StubContext::SetupUdbContext(InterruptContext *pCxt, StubContext *pUdbCxt)
{
    pUdbCxt->eax = pCxt->eax;
    pUdbCxt->ebx = pCxt->ebx;
    pUdbCxt->ecx = pCxt->ecx;
    pUdbCxt->edx = pCxt->edx;
    pUdbCxt->esi = pCxt->esi;
    pUdbCxt->edi = pCxt->edi;
    pUdbCxt->ebp = pCxt->ebp;
    pUdbCxt->es = pCxt->es;
    pUdbCxt->ds = pCxt->ds;

    pUdbCxt->eflags = pCxt->eflags;
    pUdbCxt->cs = pCxt->cs;
    pUdbCxt->eip = pCxt->eip;

    pUdbCxt->ss = pCxt->_ss;
    pUdbCxt->esp = pCxt->_esp;

    ASM("movl %%gs, %0;"
        "movl %%fs, %1;"
        :"=r"(pUdbCxt->gs), "=r"(pUdbCxt->fs)
        );
}

void StubContext::RestoreUdbInterruptContext(InterruptContext *pCxt,
    StubContext *pUdbCxt)
{
    pCxt->eax = pUdbCxt->eax;
    pCxt->ebx = pUdbCxt->ebx;
    pCxt->ecx = pUdbCxt->ecx;
    pCxt->edx = pUdbCxt->edx;
    pCxt->esi = pUdbCxt->esi;
    pCxt->edi = pUdbCxt->edi;
    pCxt->ebp = pUdbCxt->ebp;
    pCxt->es = pUdbCxt->es;
    pCxt->ds = pUdbCxt->ds;

    pCxt->eflags = pUdbCxt->eflags;
    pCxt->cs = pUdbCxt->cs;
    pCxt->eip = pUdbCxt->eip;

    pCxt->_esp = pUdbCxt->esp;
    pCxt->_ss = pUdbCxt->ss;
}
#endif //if defined(_UDBAGENT)

#if defined(_KDBAGENT)
void StubContext::SetupKdbContext(InterruptContext *pCxt, StubContext *pKdbCxt)
{
    pKdbCxt->eax = pCxt->eax;
    pKdbCxt->ebx = pCxt->ebx;
    pKdbCxt->ecx = pCxt->ecx;
    pKdbCxt->edx = pCxt->edx;
    pKdbCxt->esi = pCxt->esi;
    pKdbCxt->edi = pCxt->edi;
    pKdbCxt->ebp = pCxt->ebp;
    pKdbCxt->es = pCxt->es;
    pKdbCxt->ds = pCxt->ds;

    pKdbCxt->eflags = pCxt->eflags;
    pKdbCxt->cs = pCxt->cs;
    pKdbCxt->eip = pCxt->eip;

    pKdbCxt->ss = KERNEL_DATA_SELECTOR;
    pKdbCxt->esp = (uint_t)pCxt + (uint_t)offsetof(InterruptContext, _esp);

    ASM("movl %%gs, %0;"
        "movl %%fs, %1;"
        :"=r"(pKdbCxt->gs), "=r"(pKdbCxt->fs)
        );
}

void StubContext::RestoreKdbInterruptContext(InterruptContext *pCxt,
    StubContext *pKdbCxt)
{
    pCxt->eax = pKdbCxt->eax;
    pCxt->ebx = pKdbCxt->ebx;
    pCxt->ecx = pKdbCxt->ecx;
    pCxt->edx = pKdbCxt->edx;
    pCxt->esi = pKdbCxt->esi;
    pCxt->edi = pKdbCxt->edi;
    pCxt->ebp = pKdbCxt->ebp;
    pCxt->es = pKdbCxt->es;
    pCxt->ds = pKdbCxt->ds;

    pCxt->eflags = pKdbCxt->eflags;
    pCxt->cs = pKdbCxt->cs;
    pCxt->eip = pKdbCxt->eip;

    //pCxt->_esp = pKdbCxt->esp;
    //pCxt->_ss = pKdbCxt->ss;
}

void SwitchToKdbStack(UInt32 uKdbStack)
{
    ASM(
        "movl %0, %%esp;"
        "movl 0x10(%%ebp), %%ecx;"
        "pushl %%ecx;"
        "movl 0xc(%%ebp), %%ecx;"
        "pushl %%ecx;"
        "movl 0x8(%%ebp), %%ecx;"
        "pushl %%ecx;"
        "movl 0x4(%%ebp), %%ecx;"
        "pushl %%ecx;"
        "movl 0(%%ebp), %%ecx;"
        "pushl %%ecx;"
        "movl %%esp, %%ebp;"
        ::"m"(uKdbStack)
        );
}
#endif //if defined(_KDBAGENT)
